#include "MessageHelper.h"
#include "Global.h"


namespace Gnodroid {

    bool
    MessageHelper::receiveMessage(char *&buff, gssize &size, Glib::RefPtr<Gio::Socket> socket)
    {
        gint32 dataSize = 0;    //总大小
        gint32 recSize = 0;     //单次收到的大小
        char buffDataSize[4];   //消息的大小前缀
        gssize readSize = 0;    //累计收到的大小
        char* buffRecData = nullptr;

        try {

            //首先接受数据长度
            recSize = socket->receive(buffDataSize, 4);
            if (recSize == 0 || recSize == -1) {
                return false;
            }
            dataSize = *reinterpret_cast<gint32*>(buffDataSize);
            //网络字节序转为本地字节序
            dataSize = g_ntohl(dataSize);
            buffRecData = new char[dataSize];     //消息缓冲区
            //buffRecData[dataSize] = '\0';
            //读取数据
            recSize = socket->receive(buffRecData, dataSize);
            if (recSize == 0 || recSize == -1) {
                delete [] buffRecData;
                return false;
            }
            readSize += recSize;
            while (readSize != dataSize) {
                recSize = socket->receive(buffRecData + readSize, dataSize - readSize);
                if (recSize == 0 || recSize == -1) {
                    delete [] buffRecData;
                    return false;
                }
                readSize += recSize;
            }

        } catch (...) {
            if (buffRecData) {
                delete [] buffRecData;
            }
            return false;
        }

        buff = buffRecData;
        size = dataSize;
        return true;
    }


    bool
    MessageHelper::sendMessage(const char *data, gssize size, Glib::RefPtr<Gio::Socket> socket)
    {
        if (size == 0) {
            LOG_ERROR("send size can not be zero");
            return false;
        }

        gint32 _size = (gint32) size;
        gint32 _sizeBE = g_htonl(_size);        //本机字节序转为网络字节序
        gssize writeSize = 0;
        gssize sendSize = 0;

        try {
            //首先发送数据长度
            sendSize = socket->send(reinterpret_cast<char*>(&_sizeBE), 4);
            if (sendSize == 0 || sendSize == -1) {
                return false;
            }
            //发送数据
            sendSize = socket->send(data, size);
            if (sendSize == 0 || sendSize == -1) {
                return false;
            }
            writeSize += sendSize;

            while (writeSize != size) {
                sendSize = socket->send(data + writeSize, size - writeSize);
                if (sendSize == 0 || sendSize == -1) {
                    return false;
                }
                writeSize += sendSize;
            }

        } catch (...) {
            return false;
        }
        return true;
    }

}
